# gozerbot/utils/locking.py
#
#

""" generic functions """

__status__ = "seen"

## gozerbot imports

from log import rlog, loglevel
from trace import whichmodule
from lockmanager import lockmanager, rlockmanager

## basic imports

import logging
import sys

## defines

locks = []

## lockdec decorator

def lockdec(lock):

    """ locking decorator. """

    def locked(func):
        """ locking function for %s """ % str(func)

        def lockedfunc(*args, **kwargs):
            """ the locked function. """
            if loglevel <= 1:
                where = whichmodule(1)
                rlog(1, 'locking', 'locking on %s (%s)' % (where, str(func)))
            lock.acquire()
            locks.append(str(func))
            res = None
            try: res = func(*args, **kwargs)
            finally: lock.release() ; locks.remove(str(func))
            return res

        return lockedfunc

    return locked

## funclocked decorator

def funclocked(func):

    """ locking function for %s """ % str(func)

    def lockedfunc(*args, **kwargs):
        """ the locked function. """
        if loglevel <= 1:
            where = whichmodule(1)
            rlog(1, 'locking', 'locking on %s' % where)
        rlockmanager.acquire(func)
        locks.append(str(func))
        res = None
        try: res = func(*args, **kwargs)
        finally: rlockmanager.release(func) ; locks.remove(str(func))
        return res

    return lockedfunc

## Locked class

class Locked(object):

    """ class used to lock an entire object. """

    def __getattribute__(self, attr):
        """ lock on attribute access. """
        if loglevel <= 1:
            where = whichmodule(1)
            rlog(1, 'locking', 'locking on %s' % where)
        rlockmanager.acquire(object)
        res = None
        try: res = super(Locked, self).__getattribute__(attr)
        finally: rlockmanager.release(object)
        return res

#### BHJTW 22-01-2012
